#include <stdio.h>
#include "../memorypool.h"
#include <vector>
#include "../../tinyxml/tinyxml.h"
#include <queue>
#include <stdlib.h>
#ifdef _WIN32
#include <Windows.h>
#include "..\..\pthread\pthread.h"
#else
#include <pthread.h>
#include <iostream>
#include <time.h>

typedef unsigned int	DWORD;
DWORD GetTickCount()
{
	struct timespec		ts	= {0};

	clock_gettime(CLOCK_MONOTONIC, &ts);
	
	return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
}

#endif

// #define MAX_TEST			10000000
#define MAX_TEST			100000

class A : public mpool::object
{
public:
	A()
	{
		i = 0;
	}

	A(int a)
	{
		i = a;
	}

	~A()
	{
		int i = 0;
	}
private:
	int			i;
};

void* test(void*);

DWORD					all		= 0;
pthread_mutex_t			mutex	= PTHREAD_MUTEX_INITIALIZER;

int main(void)
{
// 	mpool::pack_memory		pack(0);
// 
// 	//std::map::iterator
// 	unsigned char *str = pack.get();

// 	for(int i = 0; i < 2; i++)
// 	{
// 		mpool::string_base<4>	str;
// 
// 		str.format("he%s", "llo");
// 		str.append(" %s", "world!");
// 		str.append(" %s", " j you is ok!");
// 		str.append(" %t", time(NULL));
// 		str.append(" %q", "hh'ddd'sss");
// 	}

// 	std::vector<int, myallocator>		vct;
// 	std::allocator
//	std::vector< int, allocator<int> >		vct;

// 	//std::vector< int, mpool::allocator<int> >		vct;
// 	std::vector< int, mpool::allocator<int> >		vct;
// 	std::vector< int, mpool::allocator<int> >		vct2;
// 	std::basic_string< char, std::char_traits<char>, mpool::allocator<char> > str;
// 
// //	vct.reserve(1024);
//  //	vct.push_back(1);
// 	vct.push_back(33);
// 	vct.push_back(22);
// 	vct.push_back(11);
// 	vct.push_back(44);
// 	vct.push_back(55);
// 	vct.push_back(66);
// 	vct.push_back(77);
// 	vct2.insert(vct2.begin(), vct.begin(), vct.end());

	//std::allocator
// 	mpool::object<A>		object_A;
// 
// 	A*	a = object_A._new();
// 
// 	object_A._delete(a);

// 	A*	a = new A(3);
// 
// 	delete a;

// 	TiXmlDocument		node;
// 	char*				pxml		= "<test><Body>hilkjkhkl</Body></test>";
// 	const char *			p;
// 
// 	p = node.Parse(pxml);
// 	TiXmlElement*			soap	= node.FirstChildElement();
// 	
// 	int			start		= 0;
// 
// 	for(int i = 0; i < 32; i++)
// 	{
// 		printf("%d. %dK => %dBit(+%d)\n"
// 			, i
// 			, (8192 + i * 4096) / 1024
// 			, (8192 + i * 4096) / 32
// 			, (8192 + i * 4096) / 32 - start);
// 		start = (8192 + i * 4096) / 32;
// 	}

// 	mpool::memory		mm(36);
// 
// 	strcpy((char *)mm.get(), "hello");
// 	mm.resize(1480);

// 	for(int i = 0; i < 10000; i++)
// 	{
// 		mpool::memory	s(i);		
// 	}
	pthread_t		id[3];

	pthread_create(&id[0], NULL, test, NULL);
	pthread_create(&id[1], NULL, test, NULL);
	pthread_create(&id[2], NULL, test, NULL);
	test(NULL);
	pthread_join(id[0], NULL);
	pthread_join(id[1], NULL);
	pthread_join(id[2], NULL);

	printf("test memory pool:"
		"  all: %d \n"
		"  alltime: %d\n"
		"  avg: %d\n",
		MAX_TEST * 4,
		all, all / 4);

	all = 0;
	pthread_create(&id[0], NULL, test, (void*)1);
	pthread_create(&id[1], NULL, test, (void*)1);
	pthread_create(&id[2], NULL, test, (void*)1);
	test((void*)1);
	pthread_join(id[0], NULL);
	pthread_join(id[1], NULL);
	pthread_join(id[2], NULL);

	printf("test raw memory:"
		"  all: %d \n"
		"  alltime: %d\n"
		"  avg: %d\n",
		MAX_TEST * 4,
		all, all / 4);

	system("pause");
	return 0;
}

void* test(void* p)
{
	DWORD		dwTickCount	= GetTickCount();

	srand((int)time(NULL));
	for(int i = 0; i < MAX_TEST; i++)
	{
		if(NULL == p)
		{
			size_t				size	= (size_t)rand() % (1024 * 256)  + 1;
			mpool::memory		s(size);

			memset(s.get(), 0xfe, 1);
		}
		else
		{
			void*	s	= malloc((size_t)rand() % (1024 * 256)  + 1);

			memset(s, 0xfe, 1);
			free(s);
		}
	}

	pthread_mutex_lock(&mutex);
	all += GetTickCount() - dwTickCount;
	pthread_mutex_unlock(&mutex);

	return NULL;
}
